/**
 * @version 1.8
 * @Author Djx_hmbb
 * @Date 2023/8/18 12:48
 * @注释:自行实现队列（插入、取出）
 * put 和 take 中的阻塞不会同时运行,因为执行条件是 size 为空或者为满
 */

class MyBlockingQueue{
    private int[] arr = new int[5];
    private int tail = 0;
    private int head = 0;
    private int size = 0;

    //入队
    public void put(int i) throws InterruptedException {
        //为了保证线程安全，加锁
        synchronized (this) {
            while (size == arr.length){
                //为满则等待(阻塞)
                this.wait();
//                return;
            }
            arr[tail] = i;
            ++tail;
            if(tail == arr.length){
                tail = 0;
            }
            ++size;
            //take中的wait
            this.notify();
        }
    }

    //出队
    public Integer take() throws InterruptedException {
        //为了保证线程安全，加锁
        synchronized (this) {
            //为空则等待(阻塞)
            if (size == 0) {
                this.wait();
//                return null;
            }
            int tmp = arr[head];
            ++head;
            if (head == arr.length) {
                head = 0;
            }
            --size;
            //put中的wait
            this.notify();
            return tmp;
        }
    }
}


public class ThreadDemo19 {
    public static void main(String[] args) throws InterruptedException {
       /* MyQueue myQueue = new MyQueue();
        myQueue.put(1);
        myQueue.put(2);
        myQueue.put(3);
        myQueue.put(4);
        myQueue.put(5);
        System.out.println(myQueue.take());
        myQueue.put(6);
        System.out.println(myQueue.take());
        System.out.println(myQueue.take());
        System.out.println(myQueue.take());
        System.out.println(myQueue.take());
        System.out.println(myQueue.take());*/


//        进行消费者和生产者的演示
        //总是先生产再消费
        MyBlockingQueue myQueue = new MyBlockingQueue();

        //消费者
        Thread customer = new Thread(()->{
           while(true){
               try {
                   System.out.println("消费 : " + myQueue.take());
                   Thread.sleep(500);//消费慢,生产快//达到数组上限后,生产消费者会一一出现
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
           }
        });
        customer.start();

        //生产者
        Thread producer = new Thread(()->{
            int num = 0;
            while (true){
                try {
                    myQueue.put(num);
                    System.out.println("生产 : " + num);
                    ++num;
//                    Thread.sleep(500);//生产慢,消费快//生产消费者会一一出现
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        producer.start();
    }
}
